package com.berchen.controller;

import com.berchen.common.result.Result;
import com.berchen.utils.FileUtils;
import com.berchen.utils.Log4jUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDate;

/**
 * 自己写文件上传下载
 */
@RequestMapping("file")
@RestController
public class FileContrller {

    private static Logger logger = Logger.getLogger(FileContrller.class);

    @Value("${file.path}")
    private String ROOTPATH;
    /**
     * 上传文件到本地文件库
     * @return
     */
    @PostMapping("/upload.cwh")
    public Result uploadFile(@RequestParam("file") MultipartFile file){

        try{
            LocalDate now = LocalDate.now();
            String path=ROOTPATH+ File.separator+now.getYear()+File.separator+now.getMonthValue();
            File filePath = new File(path);
            if(!filePath.exists()){
                filePath.mkdirs();
            }

            String fileName= file.getOriginalFilename();
            fileName= FileUtils.getFileName(fileName);
            if(fileName.indexOf(".")!=-1){
                fileName=fileName.substring(0,fileName.lastIndexOf("."))+"_"+System.currentTimeMillis()+"."+fileName.substring(fileName.lastIndexOf(".")+1);
            }
            else {
                fileName=fileName+"_"+System.currentTimeMillis();
            }
            String savePath=filePath+File.separator+fileName;
            System.out.println(savePath);
            // 直接使用Spring的方法写入文件
//            FileCopyUtils.copy(file.getBytes(), new File(savePath));

            // 直接使用MultipartFile 的方法将文件写入到指定的路径下
            file.transferTo(new File(savePath));


            return Result.ok(now.getYear()+File.separator+now.getMonthValue()+File.separator+fileName);
        }catch (Exception e){

            logger.error(Log4jUtils.getTrace(e));
            return Result.error();
        }
    }

    /**
     * 下载文件
     * 路径 http://localhost:8085/chen-system/file/showFile.cwh/home/file/2021/12/++_1639043581467.png
     * /home/file/2021/12/++_1639043581467.png 这就是文件系统中的路径
     * @param request
     * @param response
     */
    @GetMapping("download.cwh/**")
    public void download(HttpServletRequest request, HttpServletResponse response){

        showOrDownload(request,response,false);
    }

    /**
     * 展示文件
     * @param request
     * @param response
     */
    @GetMapping("showFile.cwh/**")
    public void showFile(HttpServletRequest request, HttpServletResponse response){

        showOrDownload(request,response,true);
    }

    /**
     * 查看或者下载文件
     * @param request
     * @param response
     * @param isShow    是否是查看图片
     */
    private void showOrDownload(HttpServletRequest request, HttpServletResponse response, boolean isShow){
        InputStream in=null;
        OutputStream out=null;
        try{

            // 从路径中截取参数
            String path=extractPathFromPattern(request);
            System.out.println("  hahah "+path);
            if(StringUtils.isEmpty(path)){
                return;
            }
            String filePath=ROOTPATH+File.separator+path;
            File file=new File(filePath);
            if(!file.exists()){
                response.setStatus(404);
                throw new RuntimeException("文件不存在...");
            }
            if(!isShow) {
                // 强制下载 不再网页打开
                response.setContentType("application/force-download");
                // 设置文件名 以附件形式下载
                response.addHeader("Content-Disposition","attachment;fileName="+new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
            }
            in=new BufferedInputStream(new FileInputStream(filePath));
            out= response.getOutputStream();

            byte[] buf=new byte[1024];
            int len;
            while ((len=in.read(buf))!=-1){
                out.write(buf,0,len);
            }
            // 刷新缓冲区
            response.flushBuffer();

        }catch (Exception e){
            logger.error(Log4jUtils.getTrace(e));
            response.setStatus(404);
        }
        finally {
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    logger.error(Log4jUtils.getTrace(e));
                }
            }
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    logger.error(Log4jUtils.getTrace(e));
                }
            }
        }
    }
    /**
     *  把指定URL后的字符串全部截断当成参数
     *  这么做是为了防止URL中包含中文或者特殊字符（/等）时，匹配不了的问题
     * @param request
     * @return
     */
    private static String extractPathFromPattern(final HttpServletRequest request) {
        String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        System.out.println("path = "+path);
        String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        System.out.println("bestMatchPattern = "+bestMatchPattern);

        return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
    }
}
